TuttleOFX
1
|
00001 #include "TextPlugin.hpp" 00002 #include "TextProcess.hpp" 00003 #include "TextDefinitions.hpp" 00004 00005 #include <terry/merge/MergeFunctors.hpp> 00006 00007 #include <tuttle/plugin/numeric/rectOp.hpp> 00008 00009 #include <boost/gil/gil_all.hpp> 00010 00011 #include <boost/mpl/bool.hpp> 00012 #include <boost/mpl/if.hpp> 00013 #include <boost/type_traits/is_same.hpp> 00014 00015 namespace tuttle { 00016 namespace plugin { 00017 namespace text { 00018 00019 TextPlugin::TextPlugin( OfxImageEffectHandle handle ) 00020 : GeneratorPlugin( handle ) 00021 { 00022 _paramText = fetchStringParam( kParamText ); 00023 _paramIsExpression = fetchBooleanParam( kParamIsExpression ); 00024 _paramFontPath = fetchStringParam( kParamFontPath ); 00025 #ifndef __WINDOWS__ 00026 _paramFont = fetchChoiceParam( kParamFont ); 00027 #endif 00028 _paramSize = fetchIntParam( kParamSize ); 00029 _paramRatio = fetchDoubleParam( kParamRatio ); 00030 _paramColor = fetchRGBAParam( kParamColor ); 00031 _paramBackgroundColor = fetchRGBAParam( kParamBackgroundColor ); 00032 _paramPosition = fetchDouble2DParam( kParamPosition ); 00033 _paramLetterSpacing = fetchDoubleParam( kParamLetterSpacing ); 00034 _paramVAlign = fetchChoiceParam( kParamVAlign ); 00035 _paramHAlign = fetchChoiceParam( kParamHAlign ); 00036 _paramVerticalFlip = fetchBooleanParam( kParamVerticalFlip ); 00037 _paramItalic = fetchBooleanParam( kParamItalic ); 00038 _paramBold = fetchBooleanParam( kParamBold ); 00039 00040 _paramMerge = fetchChoiceParam( kParamFunction ); 00041 } 00042 00043 TextProcessParams TextPlugin::getProcessParams( const OfxPointD& renderScale ) const 00044 { 00045 TextProcessParams params; 00046 00047 params._text = _paramText->getValue(); 00048 params._isExpression = _paramIsExpression->getValue(); 00049 params._fontPath = _paramFontPath->getValue(); 00050 #ifndef __WINDOWS__ 00051 params._font = _paramFont->getValue(); 00052 #endif 00053 params._fontY = _paramSize->getValue() * renderScale.y; 00054 params._fontX = params._fontY * _paramRatio->getValue(); 00055 params._fontColor = _paramColor->getValue(); 00056 params._backgroundColor = _paramBackgroundColor->getValue(); 00057 params._position = ofxToGil( _paramPosition->getValue() * renderScale ); 00058 params._letterSpacing = _paramLetterSpacing->getValue() * renderScale.x; 00059 params._vAlign = static_cast<EParamVAlign>( _paramVAlign->getValue() ); 00060 params._hAlign = static_cast<EParamHAlign>( _paramHAlign->getValue() ); 00061 params._verticalFlip = _paramVerticalFlip->getValue(); 00062 params._italic = _paramItalic->getValue(); 00063 params._bold = _paramBold->getValue(); 00064 00065 return params; 00066 } 00067 00068 void TextPlugin::getClipPreferences( OFX::ClipPreferencesSetter& clipPreferences ) 00069 { 00070 GeneratorPlugin::getClipPreferences( clipPreferences ); 00071 } 00072 00073 /** 00074 * @brief The overridden render function 00075 * @param[in] args Rendering parameters 00076 */ 00077 void TextPlugin::render( const OFX::RenderArguments& args ) 00078 { 00079 00080 using namespace boost::gil; 00081 // instantiate the render code based on the pixel depth of the dst clip 00082 OFX::EBitDepth bitDepth = _clipDst->getPixelDepth( ); 00083 OFX::EPixelComponent components = _clipDst->getPixelComponents( ); 00084 00085 switch( components ) 00086 { 00087 case OFX::ePixelComponentRGBA: 00088 { 00089 switch( bitDepth ) 00090 { 00091 case OFX::eBitDepthUByte: 00092 { 00093 render<rgba8_view_t>(args); 00094 return; 00095 } 00096 case OFX::eBitDepthUShort: 00097 { 00098 render<rgba16_view_t>(args); 00099 return; 00100 } 00101 case OFX::eBitDepthFloat: 00102 { 00103 render<rgba32f_view_t>(args); 00104 return; 00105 } 00106 case OFX::eBitDepthCustom: 00107 case OFX::eBitDepthNone: 00108 { 00109 BOOST_THROW_EXCEPTION( exception::Unsupported() 00110 << exception::user() + "Bit depth (" + mapBitDepthEnumToString(bitDepth) + ") not recognized by the plugin." ); 00111 } 00112 } 00113 } 00114 case OFX::ePixelComponentRGB: 00115 { 00116 switch( bitDepth ) 00117 { 00118 case OFX::eBitDepthUByte: 00119 { 00120 render<rgb8_view_t>(args); 00121 return; 00122 } 00123 case OFX::eBitDepthUShort: 00124 { 00125 render<rgb16_view_t>(args); 00126 return; 00127 } 00128 case OFX::eBitDepthFloat: 00129 { 00130 render<rgb32f_view_t>(args); 00131 return; 00132 } 00133 case OFX::eBitDepthCustom: 00134 case OFX::eBitDepthNone: 00135 { 00136 BOOST_THROW_EXCEPTION( exception::Unsupported() 00137 << exception::user() + "Bit depth (" + mapBitDepthEnumToString(bitDepth) + ") not recognized by the plugin." ); 00138 } 00139 } 00140 } 00141 case OFX::ePixelComponentAlpha: 00142 { 00143 switch( bitDepth ) 00144 { 00145 case OFX::eBitDepthUByte : 00146 { 00147 render<gray8_view_t>(args); 00148 return; 00149 } 00150 case OFX::eBitDepthUShort : 00151 { 00152 render<gray16_view_t>(args); 00153 return; 00154 } 00155 case OFX::eBitDepthFloat : 00156 { 00157 render<gray32f_view_t>(args); 00158 return; 00159 } 00160 case OFX::eBitDepthCustom: 00161 case OFX::eBitDepthNone: 00162 { 00163 BOOST_THROW_EXCEPTION( exception::Unsupported() 00164 << exception::user() + "Bit depth (" + mapBitDepthEnumToString(bitDepth) + ") not recognized by the plugin." ); 00165 } 00166 } 00167 } 00168 case OFX::ePixelComponentCustom: 00169 case OFX::ePixelComponentNone: 00170 { 00171 BOOST_THROW_EXCEPTION( exception::Unsupported() 00172 << exception::user() + "Pixel components (" + mapPixelComponentEnumToString(components) + ") not supported by the plugin." ); 00173 } 00174 } 00175 BOOST_THROW_EXCEPTION( exception::Unknown() ); 00176 } 00177 00178 template< class View > 00179 void TextPlugin::render( const OFX::RenderArguments& args ) 00180 { 00181 using namespace boost::gil; 00182 using namespace terry; 00183 typedef typename View::value_type Pixel; 00184 00185 EParamMerge merge = static_cast<EParamMerge>(_paramMerge->getValue()); 00186 //doGilRender<TextProcess>( *this, args ); 00187 switch( merge ) 00188 { 00189 // Functions that need alpha 00190 case eParamMergeATop: 00191 { 00192 render< View, FunctorATop >( args ); 00193 break; 00194 } 00195 case eParamMergeColor: 00196 { 00197 //render< View, FunctorColor >( args ); 00198 break; 00199 } 00200 case eParamMergeConjointOver: 00201 { 00202 render< View, FunctorConjointOver >( args ); 00203 break; 00204 } 00205 case eParamMergeColorBurn: 00206 { 00207 render< View, FunctorColorBurn >( args ); 00208 break; 00209 } 00210 case eParamMergeColorDodge: 00211 { 00212 //render< View, FunctorColorDodge >( args ); 00213 break; 00214 } 00215 case eParamMergeDisjointOver: 00216 { 00217 //render< View, FunctorDisjointOver >( args ); 00218 break; 00219 } 00220 case eParamMergeIn: 00221 { 00222 render< View, FunctorIn >( args ); 00223 break; 00224 } 00225 case eParamMergeMask: 00226 { 00227 render< View, FunctorMask >( args ); 00228 break; 00229 } 00230 case eParamMergeMatte: 00231 { 00232 render< View, FunctorMatte >( args ); 00233 break; 00234 } 00235 case eParamMergeOut: 00236 { 00237 render< View, FunctorOut >( args ); 00238 break; 00239 } 00240 case eParamMergeOver: 00241 { 00242 render< View, FunctorOver >( args ); 00243 break; 00244 } 00245 case eParamMergeStencil: 00246 { 00247 render< View, FunctorStencil >( args ); 00248 break; 00249 } 00250 case eParamMergeUnder: 00251 { 00252 render< View, FunctorUnder >( args ); 00253 break; 00254 } 00255 case eParamMergeXOR: 00256 { 00257 render< View, FunctorXOR >( args ); 00258 break; 00259 } 00260 // Functions that doesn't need alpha 00261 case eParamMergeAverage: 00262 { 00263 render< View, FunctorAverage >( args ); 00264 break; 00265 } 00266 case eParamMergeCopy: 00267 { 00268 render< View, FunctorCopy >( args ); 00269 break; 00270 } 00271 case eParamMergeDifference: 00272 { 00273 render< View, FunctorDifference >( args ); 00274 break; 00275 } 00276 case eParamMergeDivide: 00277 { 00278 render< View, FunctorDivide >( args ); 00279 break; 00280 } 00281 case eParamMergeExclusion: 00282 { 00283 render< View, FunctorExclusion >( args ); 00284 break; 00285 } 00286 case eParamMergeFrom: 00287 { 00288 render< View, FunctorFrom >( args ); 00289 break; 00290 } 00291 case eParamMergeGeometric: 00292 { 00293 render< View, FunctorGeometric >( args ); 00294 break; 00295 } 00296 case eParamMergeHardLight: 00297 { 00298 render< View, FunctorHardLight >( args ); 00299 break; 00300 } 00301 case eParamMergeHypot: 00302 { 00303 render< View, FunctorHypot >( args ); 00304 break; 00305 } 00306 case eParamMergeLighten: 00307 { 00308 render< View, FunctorLighten >( args ); 00309 break; 00310 } 00311 case eParamMergeDarken: 00312 { 00313 render< View, FunctorDarken >( args ); 00314 break; 00315 } 00316 case eParamMergeMinus: 00317 { 00318 render< View, FunctorMinus >( args ); 00319 break; 00320 } 00321 case eParamMergeMultiply: 00322 { 00323 render< View, FunctorMultiply >( args ); 00324 break; 00325 } 00326 case eParamMergeOverlay: 00327 { 00328 render< View, FunctorOverlay >( args ); 00329 break; 00330 } 00331 case eParamMergePlus: 00332 { 00333 render< View, FunctorPlus >( args ); 00334 break; 00335 } 00336 case eParamMergeScreen: 00337 { 00338 render< View, FunctorScreen >( args ); 00339 break; 00340 } 00341 case eParamMergePinLight: 00342 { 00343 render< View, FunctorPinLight >( args ); 00344 break; 00345 } 00346 case eParamMergeReflect: 00347 { 00348 // Quadratic mode: reflect 00349 render< View, FunctorReflect >( args ); 00350 break; 00351 } 00352 case eParamMergeFreeze: 00353 { 00354 // Quadratic mode: freeze 00355 render< View, FunctorFreeze >( args ); 00356 break; 00357 } 00358 case eParamMergeInterpolated: 00359 { 00360 // Similar to average, but smoother (and a lot slower)... 00361 render< View, FunctorInterpolated >( args ); 00362 break; 00363 } 00364 } 00365 } 00366 00367 template< class View, template <typename> class Functor > 00368 void TextPlugin::render_if( const OFX::RenderArguments& args, boost::mpl::true_ ) 00369 { 00370 typedef typename View::value_type Pixel; 00371 TextProcess<View, Functor<Pixel> > p( *this ); 00372 p.setupAndProcess( args ); 00373 } 00374 00375 template< class View, template <typename> class Functor > 00376 void TextPlugin::render_if( const OFX::RenderArguments& args, boost::mpl::false_ ) 00377 { 00378 BOOST_THROW_EXCEPTION( exception::Unsupported() 00379 << exception::user() + "Need an alpha channel for this Merge operation." ); 00380 } 00381 00382 template< class View, template <typename> class Functor > 00383 void TextPlugin::render( const OFX::RenderArguments& args ) 00384 { 00385 typedef typename View::value_type Pixel; 00386 typedef typename boost::gil::contains_color< typename View::value_type, boost::gil::alpha_t>::type has_alpha_t; 00387 typedef typename boost::is_same<typename Functor<Pixel>::operating_mode_t, terry::merge_per_channel_with_alpha>::type merge_need_alpha_t; 00388 typedef typename boost::mpl::if_<merge_need_alpha_t, has_alpha_t, boost::mpl::true_>::type render_condition_t; 00389 00390 render_if<View, Functor>( args, render_condition_t() ); 00391 } 00392 00393 } 00394 } 00395 }