HRESULT
ExtendInputEffectD2D1::Register(ID2D1Factory1 *aFactory)
{
  D2D1_PROPERTY_BINDING bindings[] = {
    D2D1_VALUE_TYPE_BINDING(L"OutputRect", &ExtendInputEffectD2D1::SetOutputRect, &ExtendInputEffectD2D1::GetOutputRect),
  };
  HRESULT hr = aFactory->RegisterEffectFromString(CLSID_ExtendInputEffect, kXmlDescription, bindings, 1, CreateEffect);

  if (FAILED(hr)) {
    gfxWarning() << "Failed to register extend input effect.";
  }
  return hr;
}
HRESULT
RadialGradientEffectD2D1::Register(ID2D1Factory1 *aFactory)
{
  D2D1_PROPERTY_BINDING bindings[] = {
    D2D1_VALUE_TYPE_BINDING(L"StopCollection", &RadialGradientEffectD2D1::SetStopCollection,
                            &RadialGradientEffectD2D1::GetStopCollection),
    D2D1_VALUE_TYPE_BINDING(L"Center1", &RadialGradientEffectD2D1::SetCenter1, &RadialGradientEffectD2D1::GetCenter1),
    D2D1_VALUE_TYPE_BINDING(L"Center2", &RadialGradientEffectD2D1::SetCenter2, &RadialGradientEffectD2D1::GetCenter2),
    D2D1_VALUE_TYPE_BINDING(L"Radius1", &RadialGradientEffectD2D1::SetRadius1, &RadialGradientEffectD2D1::GetRadius1),
    D2D1_VALUE_TYPE_BINDING(L"Radius2", &RadialGradientEffectD2D1::SetRadius2, &RadialGradientEffectD2D1::GetRadius2),
    D2D1_VALUE_TYPE_BINDING(L"Transform", &RadialGradientEffectD2D1::SetTransform, &RadialGradientEffectD2D1::GetTransform)
  };
  HRESULT hr = aFactory->RegisterEffectFromString(CLSID_RadialGradientEffect, kXmlDescription, bindings, ARRAYSIZE(bindings), CreateEffect);

  if (FAILED(hr)) {
    gfxWarning() << "Failed to register radial gradient effect.";
  }
  return hr;
}
                    <Property name='Min' type='float' value='0.0001' />
                    <Property name='Max' type='float' value='1000.0' />
                    <Property name='Default' type='float' value='0.0' />
                </Property>
                <Property name='Center' type='vector2'>
                    <Property name='DisplayName' type='string' value='Center'/>
                    <Property name='Default' type='vector2' value='(0.0, 0.0)' />
                </Property>
            </Effect>
            );

    // This defines the bindings from specific properties to the callback functions
    // on the class that ID2D1Effect::SetValue() & GetValue() will call.
    const D2D1_PROPERTY_BINDING bindings[] =
    {
        D2D1_VALUE_TYPE_BINDING(L"Frequency", &SetFrequency, &GetFrequency),
        D2D1_VALUE_TYPE_BINDING(L"Phase", &SetPhase, &GetPhase),
        D2D1_VALUE_TYPE_BINDING(L"Amplitude", &SetAmplitude, &GetAmplitude),
        D2D1_VALUE_TYPE_BINDING(L"Spread", &SetSpread, &GetSpread),
        D2D1_VALUE_TYPE_BINDING(L"Center", &SetCenter, &GetCenter),
    };

    // This registers the effect with the factory, which will make the effect
    // instantiatable.
    return pFactory->RegisterEffectFromString(
        CLSID_CustomRippleEffect,
        pszXml,
        bindings,
        ARRAYSIZE(bindings),
        CreateRippleImpl
        );
                    <Property name='Min' type='float' value='-5.0'/>
                    <Property name='Max' type='float' value='5.0'/>
                    <Property name='Default' type='float' value='0.0'/>
                </Property>
            </Effect>
            );

    // Property bindings are performed automatically for the system properties.
    // For effect-specific properties (i.e. WaveOffset), you must direct
    // Direct2D to the specific method in your implementation for manipulating
    // the property. This is done by assigning each property a 'setter' and 'getter'
    // in this table. Direct2D provides a set of helpers for doing this in
    // D2D1EffectHelpers.h, such as D2D1_VALUE_TYPE_BINDING used here.
    D2D1_PROPERTY_BINDING bindings[] =
    {
        D2D1_VALUE_TYPE_BINDING(L"WaveOffset",  &SetWaveOffset,  &GetWaveOffset),
        D2D1_VALUE_TYPE_BINDING(L"SkewX",  &SetSkewX,  &GetSkewX),
        D2D1_VALUE_TYPE_BINDING(L"SkewY",  &SetSkewY,  &GetSkewY)
    };

    // Register the effect using the data defined above.
    return pFactory->RegisterEffectFromString(
        CLSID_CustomWaveEffect,
        propertyXml,
        bindings,
        ARRAYSIZE(bindings),
        CreateWaveImpl
        );
}

WaveEffect::WaveEffect() :