TuttleOFX
1
|
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 }