TuttleOFX  1
TextPluginFactory.cpp
Go to the documentation of this file.
00001 #include "TextPluginFactory.hpp"
00002 #include "TextPlugin.hpp"
00003 #include "TextDefinitions.hpp"
00004 
00005 #include <tuttle/plugin/ImageGilProcessor.hpp>
00006 #include <tuttle/plugin/context/GeneratorPluginFactory.hpp>
00007 
00008 #ifndef __WINDOWS__
00009 #include <fontconfig/fontconfig.h>
00010 #endif
00011 
00012 #include <iostream>
00013 
00014 #include <boost/algorithm/string.hpp>
00015 
00016 #include <limits>
00017 
00018 namespace tuttle {
00019 namespace plugin {
00020 namespace text {
00021 
00022 /**
00023  * @brief Function called to describe the plugin main features.
00024  * @param[in, out] desc Effect descriptor
00025  */
00026 void TextPluginFactory::describe( OFX::ImageEffectDescriptor& desc )
00027 {
00028         desc.setLabels( "TuttleText",
00029                                         "Text",
00030                                         "Text" );
00031         desc.setPluginGrouping( "tuttle/image/generator" );
00032 
00033         // add the supported contexts
00034         desc.addSupportedContext( OFX::eContextGenerator );
00035         desc.addSupportedContext( OFX::eContextGeneral );
00036 
00037         // add supported pixel depths
00038         desc.addSupportedBitDepth( OFX::eBitDepthUByte );
00039         desc.addSupportedBitDepth( OFX::eBitDepthUShort );
00040         desc.addSupportedBitDepth( OFX::eBitDepthFloat );
00041 
00042         // plugin flags
00043         desc.setRenderThreadSafety( OFX::eRenderFullySafe );
00044         desc.setHostFrameThreading( false );
00045         desc.setSupportsMultiResolution( false );
00046         desc.setSupportsMultipleClipDepths( true );
00047         desc.setSupportsTiles( kSupportTiles );
00048 }
00049 
00050 /**
00051  * @brief Function called to describe the plugin controls and features.
00052  * @param[in, out]   desc       Effect descriptor
00053  * @param[in]        context    Application context
00054  */
00055 void TextPluginFactory::describeInContext( OFX::ImageEffectDescriptor& desc,
00056                                            OFX::EContext               context )
00057 {
00058         describeGeneratorParamsInContext( desc, context );
00059 
00060         OFX::StringParamDescriptor* text = desc.defineStringParam( kParamText );
00061         text->setLabel( "Text" );
00062         text->setStringType( OFX::eStringTypeMultiLine );
00063 
00064         OFX::BooleanParamDescriptor* isExpression = desc.defineBooleanParam( kParamIsExpression );
00065         isExpression->setLabel( "Expression" );
00066         isExpression->setHint( "If you check this parameter the text must be a python code.\n"
00067                                "The final result must be in a variable with the name of the parameter.\n"
00068                                "Example:\n"
00069                                "text = 'text=\"str(tuttleArgs().time)\"\n"
00070                                "or\n"
00071                                "text = 'text=\"tuttleArgs().timecode()\"\n"
00072                                );
00073         isExpression->setDefault( false );
00074         
00075 
00076         OFX::StringParamDescriptor* fontFile = desc.defineStringParam( kParamFontPath );
00077         fontFile->setStringType( OFX::eStringTypeFilePath );
00078         fontFile->setHint( "When a font file path is fill, font & bold and italic options are not available." );
00079 
00080 #ifndef __WINDOWS__
00081         OFX::ChoiceParamDescriptor* font = desc.defineChoiceParam( kParamFont );
00082 
00083         FcInit ();
00084         FcConfig *config = FcInitLoadConfigAndFonts();
00085         FcChar8 *s;
00086         FcPattern *p  = FcPatternBuild( NULL, 
00087                                                                         FC_WEIGHT, FcTypeInteger, FC_WEIGHT_BOLD, 
00088                                                                         FC_SLANT, FcTypeInteger, FC_SLANT_ITALIC, 
00089                                                                         NULL );
00090 
00091         FcObjectSet *os = FcObjectSetBuild( FC_FAMILY, NULL );
00092         FcFontSet   *fs = FcFontList( config, p, os );
00093 
00094         for( int i=0; fs && i < fs->nfont; i++ )
00095         {
00096                 FcPattern *fcFont = fs->fonts[ i ];
00097                 s = FcNameUnparse( fcFont );
00098         
00099                 std::ostringstream stream ;
00100                 stream << s ;
00101                 std::string id = stream.str();
00102                 boost::algorithm::to_lower( id );
00103                 boost::replace_all ( id, " ", "_" );
00104         
00105                 font->appendOption( id, stream.str() );
00106                 
00107                 if(!strcmp((char*)s, "Arial"))
00108                         font->setDefault( i );  
00109         }
00110         font->setHint("Select the font.");
00111         font->setLabel("Font");
00112 #endif
00113         OFX::IntParamDescriptor* size = desc.defineIntParam( kParamSize );
00114         size->setLabel( "Font Size" );
00115         size->setDefault( 18 );
00116         size->setRange( 0, std::numeric_limits<int>::max() );
00117         size->setDisplayRange( 0, 60 );
00118 /*
00119         OFX::DoubleParamDescriptor* ratio = desc.defineDoubleParam( kParamRatio );
00120         ratio->setLabel( "Ratio" );
00121         ratio->setRange( 0.0, std::numeric_limits<double>::max() );
00122         ratio->setDisplayRange( 0.0, 2.0 );
00123         ratio->setDefault( 1.0 );
00124 */
00125         OFX::RGBAParamDescriptor* color = desc.defineRGBAParam( kParamColor );
00126         color->setLabel( "Color" );
00127         color->setDefault( 1.0, 1.0, 1.0, 1.0 );
00128 
00129         OFX::RGBAParamDescriptor* backgroundColor = desc.defineRGBAParam( kParamBackgroundColor );
00130         backgroundColor->setLabel( "Background Color" );
00131         backgroundColor->setDefault( 0.0, 0.0, 0.0, 0.0 );
00132 
00133         OFX::Double2DParamDescriptor* position = desc.defineDouble2DParam( kParamPosition );
00134         position->setLabel( "Position" );
00135         position->setDefault( 0.0, 0.0 );
00136 
00137         OFX::DoubleParamDescriptor* letterSpacing = desc.defineDoubleParam( kParamLetterSpacing );
00138         letterSpacing->setLabel( "Letter spacing" );
00139         letterSpacing->setDisplayRange( -10.0, 10.0 );
00140         letterSpacing->setDefault( 0.0 );
00141 
00142         OFX::ChoiceParamDescriptor* vAlign = desc.defineChoiceParam( kParamVAlign );
00143         vAlign->setLabel( "Vertically align" );
00144         vAlign->appendOption( kParamVAlignTop );
00145         vAlign->appendOption( kParamVAlignCenter );
00146         vAlign->appendOption( kParamVAlignBottom );
00147         vAlign->setDefault( eParamVAlignCenter );
00148 
00149         OFX::ChoiceParamDescriptor* hAlign = desc.defineChoiceParam( kParamHAlign );
00150         hAlign->setLabel( "Horizontally align" );
00151         hAlign->appendOption( kParamHAlignLeft );
00152         hAlign->appendOption( kParamHAlignCenter );
00153         hAlign->appendOption( kParamHAlignRight );
00154         hAlign->setDefault( eParamHAlignCenter );
00155 
00156         OFX::BooleanParamDescriptor* verticalFlip = desc.defineBooleanParam( kParamVerticalFlip );
00157         verticalFlip->setLabel( "Vertical flip" );
00158         verticalFlip->setDefault( false );
00159         verticalFlip->setAnimates( false );
00160         verticalFlip->setHint( "Some hosts use inverted images, so you can correct this problem using this flag." );
00161 
00162         OFX::BooleanParamDescriptor* italic = desc.defineBooleanParam( kParamItalic );
00163         italic->setLabel( "Italic" );
00164         italic->setDefault( false );
00165 
00166         OFX::BooleanParamDescriptor* bold = desc.defineBooleanParam( kParamBold );
00167         bold->setLabel( "Bold" );
00168         bold->setDefault( false );
00169 
00170         // Define some merging function
00171         OFX::ChoiceParamDescriptor* mergeFunction = desc.defineChoiceParam( kParamFunction );
00172         mergeFunction->setLabels( kParamFunctionLabel, kParamFunctionLabel, kParamFunctionLabel );
00173         mergeFunction->appendOption( "atop", "atop: Ab+B(1-a)" );
00174         mergeFunction->appendOption( "average", "average: (A+B)/2" );
00175         mergeFunction->appendOption( "color", "color: hue from B, saturation from B, lightness from A" );
00176         mergeFunction->appendOption( "color-burn", "color-burn: darken B towards A" );
00177         mergeFunction->appendOption( "color dodge inversed", "color dodge inversed: brighten B towards A" );
00178         mergeFunction->appendOption( "conjoint-over", "conjoint-over: A+B(1-a)/b, A if a > b" );
00179         mergeFunction->appendOption( "copy", "copy: A" );
00180         mergeFunction->appendOption( "difference", "difference: abs(A-B)" );
00181         mergeFunction->appendOption( "disjoint-over", "disjoint-over: A+B(1-a)/b, A+B if a+b < 1" );
00182         mergeFunction->appendOption( "divide", "divide: A/B, 0 if A < 0 and B < 0" );
00183         mergeFunction->appendOption( "exclusion", "exclusion: A+B-2AB" );
00184         mergeFunction->appendOption( "freeze", "freeze: 1-sqrt(1-A)/B" );
00185         mergeFunction->appendOption( "from", "from: B-A" );
00186         mergeFunction->appendOption( "geometric", "geometric: 2AB/(A+B)" );
00187         mergeFunction->appendOption( "hard-light", "hard-light: multiply if A < 0.5, screen if A > 0.5" );
00188         mergeFunction->appendOption( "hypot", "hypot: sqrt(A*A+B*B)" );
00189         mergeFunction->appendOption( "in", "in: Ab" );
00190         mergeFunction->appendOption( "interpolated", "interpolated: (like average but better and slower)" );
00191         mergeFunction->appendOption( "mask", "mask: Ba" );
00192         mergeFunction->appendOption( "matte", "matte: Aa + B(1-a) (unpremultiplied over)" );
00193         mergeFunction->appendOption( "lighten", "lighten: max(A, B)" );
00194         mergeFunction->appendOption( "darken", "darken: min(A, B)" );
00195         mergeFunction->appendOption( "minus", "minus: A-B" );
00196         mergeFunction->appendOption( "multiply", "multiply: AB, 0 if A < 0 and B < 0" );
00197         mergeFunction->appendOption( "out", "out: A(1-b)" );
00198         mergeFunction->appendOption( "over", "over: A+B(1-a)" );
00199         mergeFunction->appendOption( "overlay", "overlay: multiply if B<0.5, screen if B>0.5" );
00200         mergeFunction->appendOption( "pinlight", "pinlight: if B >= 0.5 then max(A, 2*B - 1), min(A, B * 2.0 ) else" );
00201         mergeFunction->appendOption( "plus", "plus: A+B" );
00202         mergeFunction->appendOption( "reflect", "reflect: a² / (1 - b)" );
00203         mergeFunction->appendOption( "screen", "screen: A+B-AB" );
00204         mergeFunction->appendOption( "stencil", "stencil: B(1-a)" );
00205         mergeFunction->appendOption( "under", "under: A(1-b)+B" );
00206         mergeFunction->appendOption( "xor", "xor: A(1-b)+B(1-a)" );
00207         mergeFunction->setDefault( eParamMergePlus );
00208 }
00209 
00210 /**
00211  * @brief Function called to create a plugin effect instance
00212  * @param[in] handle  Effect handle
00213  * @param[in] context Application context
00214  * @return  plugin instance
00215  */
00216 OFX::ImageEffect* TextPluginFactory::createInstance( OfxImageEffectHandle handle,
00217                                                      OFX::EContext        context )
00218 {
00219         return new TextPlugin( handle );
00220 }
00221 
00222 }
00223 }
00224 }