TuttleOFX  1
TextPlugin.cpp
Go to the documentation of this file.
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 }