public void HighlightsAndShadowsEffectCustomizations() { const uint D2D1_HIGHLIGHTSANDSHADOWS_INPUT_GAMMA_LINEAR = 0; const uint D2D1_HIGHLIGHTSANDSHADOWS_INPUT_GAMMA_SRGB = 1; var effect = new HighlightsAndShadowsEffect(); // Verify defaults. Assert.IsFalse(effect.SourceIsLinearGamma); Assert.AreEqual(D2D1_HIGHLIGHTSANDSHADOWS_INPUT_GAMMA_SRGB, EffectAccessor.GetProperty(effect, 3)); // Change the property, and verify that the boxed value changes to match. effect.SourceIsLinearGamma = true; Assert.IsTrue(effect.SourceIsLinearGamma); Assert.AreEqual(D2D1_HIGHLIGHTSANDSHADOWS_INPUT_GAMMA_LINEAR, EffectAccessor.GetProperty(effect, 3)); effect.SourceIsLinearGamma = false; Assert.IsFalse(effect.SourceIsLinearGamma); Assert.AreEqual(D2D1_HIGHLIGHTSANDSHADOWS_INPUT_GAMMA_SRGB, EffectAccessor.GetProperty(effect, 3)); // Validate that IGraphicsEffectD2D1Interop reports the right customizations. int index; EffectPropertyMapping mapping; EffectAccessor.GetNamedPropertyMapping(effect, "SourceIsLinearGamma", out index, out mapping); Assert.AreEqual(3, index); Assert.AreEqual(EffectPropertyMapping.Unknown, mapping); }
static void TestEffectInterop(CanvasDevice device, CanvasDevice device2, TypeInfo effectType, IGraphicsEffect realizedEffect) { // One Win2D effect is backed by a realized ID2D1Effect instance, the other is not. // Their property values should be the same either way. IGraphicsEffect unrealizedEffect = (IGraphicsEffect)Activator.CreateInstance(effectType.AsType()); PropertyValuesShouldMatch(effectType, realizedEffect, unrealizedEffect); // Create a new ID2D1Effect instance, then wrap a Win2D effect around it. // We should get the same default property values either way. IGraphicsEffect wrappedEffect = EffectAccessor.CreateThenWrapNewEffectOfSameType(device, realizedEffect); // Special case: Win2D intentionally defaults to a different DpiCompensationEffect.BorderMode vs. D2D. if (wrappedEffect is DpiCompensationEffect) { var dpiCompensationEffect = wrappedEffect as DpiCompensationEffect; Assert.AreEqual(EffectBorderMode.Soft, dpiCompensationEffect.BorderMode); dpiCompensationEffect.BorderMode = EffectBorderMode.Hard; } PropertyValuesShouldMatch(effectType, unrealizedEffect, wrappedEffect); // Re-realize the new effect onto a second device. // All property values should be successfully transferred across. RealizeEffect(device2, effectType, wrappedEffect); PropertyValuesShouldMatch(effectType, unrealizedEffect, wrappedEffect); }
public void EdgeDetectionEffectCustomizations() { var effect = new EdgeDetectionEffect(); // Verify defaults. Assert.AreEqual(CanvasAlphaMode.Premultiplied, effect.AlphaMode); Assert.AreEqual(D2D1_ALPHA_MODE_PREMULTIPLIED, EffectAccessor.GetProperty(effect, 4)); // Change the property, and verify that the boxed value changes to match. effect.AlphaMode = CanvasAlphaMode.Straight; Assert.AreEqual(D2D1_ALPHA_MODE_STRAIGHT, EffectAccessor.GetProperty(effect, 4)); effect.AlphaMode = CanvasAlphaMode.Premultiplied; Assert.AreEqual(D2D1_ALPHA_MODE_PREMULTIPLIED, EffectAccessor.GetProperty(effect, 4)); // Verify unsupported value throws. Assert.ThrowsException <ArgumentException>(() => { effect.AlphaMode = CanvasAlphaMode.Ignore; }); Assert.AreEqual(CanvasAlphaMode.Premultiplied, effect.AlphaMode); // Validate that IGraphicsEffectD2D1Interop reports the right customizations. int index; EffectPropertyMapping mapping; EffectAccessor.GetNamedPropertyMapping(effect, "AlphaMode", out index, out mapping); Assert.AreEqual(4, index); Assert.AreEqual(EffectPropertyMapping.ColorMatrixAlphaMode, mapping); }
public void ArithmeticCompositeEffectCustomizations() { var effect = new ArithmeticCompositeEffect(); // Verify defaults. Assert.AreEqual(1.0f, effect.MultiplyAmount); Assert.AreEqual(0.0f, effect.Source1Amount); Assert.AreEqual(0.0f, effect.Source2Amount); Assert.AreEqual(0.0f, effect.Offset); Assert.IsTrue(((float[])EffectAccessor.GetProperty(effect, 0)).SequenceEqual(new float[] { 1, 0, 0, 0 })); // Change properties one at a time, and verify that the boxed value changes to match. effect.MultiplyAmount = 23; Assert.IsTrue(((float[])EffectAccessor.GetProperty(effect, 0)).SequenceEqual(new float[] { 23, 0, 0, 0 })); effect.Source1Amount = 42; Assert.IsTrue(((float[])EffectAccessor.GetProperty(effect, 0)).SequenceEqual(new float[] { 23, 42, 0, 0 })); effect.Source2Amount = -1; Assert.IsTrue(((float[])EffectAccessor.GetProperty(effect, 0)).SequenceEqual(new float[] { 23, 42, -1, 0 })); effect.Offset = 100; Assert.IsTrue(((float[])EffectAccessor.GetProperty(effect, 0)).SequenceEqual(new float[] { 23, 42, -1, 100 })); }
static void TestEffectProperties(TypeInfo effectType, IGraphicsEffect effect) { var properties = (from property in effectType.DeclaredProperties where property.Name != "Name" where property.Name != "Sources" where property.PropertyType != typeof(IGraphicsEffectSource) select property).ToList(); IList <object> effectProperties = new ViewIndexerAsList <object>(() => EffectAccessor.GetPropertyCount(effect), i => EffectAccessor.GetProperty(effect, i)); FilterOutCustomizedEffectProperties(effectType.AsType(), ref properties, ref effectProperties); // Should have the same number of strongly typed properties as elements in the properties collection. Assert.AreEqual(properties.Count, effectProperties.Count); // Store the initial property values. var initialValues = effectProperties.ToList(); var whichIndexIsProperty = new List <int>(); // Changing strongly typed properties should change the properties collection. for (int i = 0; i < effectProperties.Count; i++) { object testValue1 = GetArbitraryTestValue(properties[i].PropertyType, true); object testValue2 = GetArbitraryTestValue(properties[i].PropertyType, false); // Change a property value, and see which collection properties match the result. properties[i].SetValue(effect, testValue1); var matches1 = (from j in Enumerable.Range(0, effectProperties.Count) where BoxedValuesAreEqual(effectProperties[j], Box(testValue1, properties[i]), properties[i]) select j).ToList(); // Change the same property to a different value, and see which collection properties match now. properties[i].SetValue(effect, testValue2); var matches2 = (from j in Enumerable.Range(0, effectProperties.Count) where BoxedValuesAreEqual(effectProperties[j], Box(testValue2, properties[i]), properties[i]) select j).ToList(); // There should be one and only one property that matched both times. If not, // either we don't have 1 <-> 1 mapping between strongly typed properties and // collection indices, or something went wrong during the boxing type conversions. var intersection = matches1.Intersect(matches2); Assert.AreEqual(1, intersection.Count()); int whichIndexIsThis = intersection.Single(); whichIndexIsProperty.Add(whichIndexIsThis); // Change the property value back to its initial state. properties[i].SetValue(effect, Unbox(initialValues[whichIndexIsThis], properties[i])); Assert.IsTrue(BoxedValuesAreEqual(initialValues[whichIndexIsThis], effectProperties[whichIndexIsThis], properties[i])); } // Should not have any duplicate property mappings. Assert.AreEqual(whichIndexIsProperty.Count, whichIndexIsProperty.Distinct().Count()); }
static void TestEffectSources(TypeInfo effectType, IGraphicsEffect effect) { var sourceProperties = (from property in effectType.DeclaredProperties where property.PropertyType == typeof(IGraphicsEffectSource) select property).ToList(); // Should have the same number of strongly typed properties as the effect has sources. Assert.AreEqual(sourceProperties.Count, EffectAccessor.GetSourceCount(effect)); // Initial source values should all be null. for (int i = 0; i < EffectAccessor.GetSourceCount(effect); i++) { Assert.IsNull(EffectAccessor.GetSource(effect, i)); Assert.IsNull(sourceProperties[i].GetValue(effect)); } var testValue1 = new GaussianBlurEffect(); var testValue2 = new ShadowEffect(); var whichIndexIsProperty = new List <int>(); // Changing strongly typed properties should change the sources reported by IGraphicsEffectD2D1Interop. for (int i = 0; i < EffectAccessor.GetSourceCount(effect); i++) { // Change a property value, and see which source changes. sourceProperties[i].SetValue(effect, testValue1); int whichIndexIsThis = 0; while (EffectAccessor.GetSource(effect, whichIndexIsThis) != testValue1) { whichIndexIsThis++; Assert.IsTrue(whichIndexIsThis < EffectAccessor.GetSourceCount(effect)); } whichIndexIsProperty.Add(whichIndexIsThis); // Change the same property value again, and make sure the same source changes. sourceProperties[i].SetValue(effect, testValue2); Assert.AreSame(testValue2, EffectAccessor.GetSource(effect, whichIndexIsThis)); // Change the property value to null. sourceProperties[i].SetValue(effect, null); Assert.IsNull(EffectAccessor.GetSource(effect, whichIndexIsThis)); } // Should not have any duplicate property mappings. Assert.AreEqual(whichIndexIsProperty.Count, whichIndexIsProperty.Distinct().Count()); }
public void ArithmeticCompositeEffectCustomizations() { var effect = new ArithmeticCompositeEffect(); // Verify defaults. Assert.AreEqual(1.0f, effect.MultiplyAmount); Assert.AreEqual(0.0f, effect.Source1Amount); Assert.AreEqual(0.0f, effect.Source2Amount); Assert.AreEqual(0.0f, effect.Offset); Assert.IsTrue(((float[])EffectAccessor.GetProperty(effect, 0)).SequenceEqual(new float[] { 1, 0, 0, 0 })); // Change properties one at a time, and verify that the boxed value changes to match. effect.MultiplyAmount = 23; Assert.IsTrue(((float[])EffectAccessor.GetProperty(effect, 0)).SequenceEqual(new float[] { 23, 0, 0, 0 })); effect.Source1Amount = 42; Assert.IsTrue(((float[])EffectAccessor.GetProperty(effect, 0)).SequenceEqual(new float[] { 23, 42, 0, 0 })); effect.Source2Amount = -1; Assert.IsTrue(((float[])EffectAccessor.GetProperty(effect, 0)).SequenceEqual(new float[] { 23, 42, -1, 0 })); effect.Offset = 100; Assert.IsTrue(((float[])EffectAccessor.GetProperty(effect, 0)).SequenceEqual(new float[] { 23, 42, -1, 100 })); // Validate that IGraphicsEffectD2D1Interop reports the right customizations. int index; EffectPropertyMapping mapping; EffectAccessor.GetNamedPropertyMapping(effect, "MultiplyAmount", out index, out mapping); Assert.AreEqual(0, index); Assert.AreEqual(EffectPropertyMapping.VectorX, mapping); EffectAccessor.GetNamedPropertyMapping(effect, "Source1Amount", out index, out mapping); Assert.AreEqual(0, index); Assert.AreEqual(EffectPropertyMapping.VectorY, mapping); EffectAccessor.GetNamedPropertyMapping(effect, "Source2Amount", out index, out mapping); Assert.AreEqual(0, index); Assert.AreEqual(EffectPropertyMapping.VectorZ, mapping); EffectAccessor.GetNamedPropertyMapping(effect, "Offset", out index, out mapping); Assert.AreEqual(0, index); Assert.AreEqual(EffectPropertyMapping.VectorW, mapping); }
public void ColorMatrixEffectCustomizations() { const uint D2D1_COLORMATRIX_ALPHA_MODE_PREMULTIPLIED = 1; const uint D2D1_COLORMATRIX_ALPHA_MODE_STRAIGHT = 2; var effect = new ColorMatrixEffect(); // Verify defaults. Assert.AreEqual(CanvasAlphaMode.Premultiplied, effect.AlphaMode); Assert.AreEqual(D2D1_COLORMATRIX_ALPHA_MODE_PREMULTIPLIED, EffectAccessor.GetProperty(effect, 1)); // Change the property, and verify that the boxed value changes to match. effect.AlphaMode = CanvasAlphaMode.Straight; Assert.AreEqual(D2D1_COLORMATRIX_ALPHA_MODE_STRAIGHT, EffectAccessor.GetProperty(effect, 1)); effect.AlphaMode = CanvasAlphaMode.Premultiplied; Assert.AreEqual(D2D1_COLORMATRIX_ALPHA_MODE_PREMULTIPLIED, EffectAccessor.GetProperty(effect, 1)); // Verify unsupported value throws. Assert.ThrowsException <ArgumentException>(() => { effect.AlphaMode = CanvasAlphaMode.Ignore; }); Assert.AreEqual(CanvasAlphaMode.Premultiplied, effect.AlphaMode); }
static ICanvasImage RealizeEffect(CanvasDevice device, TypeInfo effectType, IGraphicsEffect effect) { var dummySourceImage = new CanvasCommandList(device); // We can't realize an effect with invalid inputs, so must first set them all to something reasonable. foreach (var sourceProperty in effectType.DeclaredProperties.Where(p => p.PropertyType == typeof(IGraphicsEffectSource))) { sourceProperty.SetValue(effect, dummySourceImage); } // Add one image to any variable size Sources collection properties. foreach (var sourcesProperty in effectType.DeclaredProperties.Where(p => p.Name == "Sources")) { var sources = sourcesProperty.GetValue(effect) as IList <IGraphicsEffectSource>; sources.Clear(); sources.Add(dummySourceImage); } EffectAccessor.RealizeEffect(device, effect); return(dummySourceImage); }
static void TestEffectProperties(TypeInfo effectType, IGraphicsEffect effect) { var properties = GetEffectProperties(effectType).ToList(); IList <object> effectProperties = new ViewIndexerAsList <object>(() => EffectAccessor.GetPropertyCount(effect), i => EffectAccessor.GetProperty(effect, i)); FilterOutCustomizedEffectProperties(effectType.AsType(), ref properties, ref effectProperties); // Should have the same number of strongly typed properties as elements in the properties collection. Assert.AreEqual(properties.Count, effectProperties.Count); // Store the initial property values. var initialValues = effectProperties.ToList(); var whichIndexIsProperty = new List <int>(); // Changing strongly typed properties should change the properties collection. for (int i = 0; i < effectProperties.Count; i++) { object testValue1 = GetArbitraryTestValue(properties[i].PropertyType, true); object testValue2 = GetArbitraryTestValue(properties[i].PropertyType, false); // Change a property value, and see which collection properties match the result. properties[i].SetValue(effect, testValue1); AssertPropertyValuesAreEqual(testValue1, properties[i].GetValue(effect)); var matches1 = (from j in Enumerable.Range(0, effectProperties.Count) where BoxedValuesAreEqual(effectProperties[j], Box(testValue1, properties[i]), properties[i]) select j).ToList(); // Change the same property to a different value, and see which collection properties match now. properties[i].SetValue(effect, testValue2); AssertPropertyValuesAreEqual(testValue2, properties[i].GetValue(effect)); var matches2 = (from j in Enumerable.Range(0, effectProperties.Count) where BoxedValuesAreEqual(effectProperties[j], Box(testValue2, properties[i]), properties[i]) select j).ToList(); // There should be one and only one property that matched both times. If not, // either we don't have 1 <-> 1 mapping between strongly typed properties and // collection indices, or something went wrong during the boxing type conversions. var intersection = matches1.Intersect(matches2); Assert.AreEqual(1, intersection.Count()); int whichIndexIsThis = intersection.Single(); whichIndexIsProperty.Add(whichIndexIsThis); // Change the property value back to its initial state. var unboxedValue = Unbox(initialValues[whichIndexIsThis], properties[i]); properties[i].SetValue(effect, unboxedValue); AssertPropertyValuesAreEqual(unboxedValue, properties[i].GetValue(effect)); Assert.IsTrue(BoxedValuesAreEqual(initialValues[whichIndexIsThis], effectProperties[whichIndexIsThis], properties[i])); // Validate that IGraphicsEffectD2D1Interop agrees with what we think the type and index of this property is. int mappingIndex; EffectPropertyMapping mapping; EffectAccessor.GetNamedPropertyMapping(effect, properties[i].Name, out mappingIndex, out mapping); int expectedMappingIndex = whichIndexIsThis; if (effectProperties is FilteredViewOfList <object> ) { expectedMappingIndex = ((FilteredViewOfList <object>)effectProperties).GetOriginalIndex(expectedMappingIndex); } Assert.AreEqual(expectedMappingIndex, mappingIndex); var expectedMapping = GetExpectedPropertyMapping(properties[i], effectProperties[whichIndexIsThis]); Assert.AreEqual(expectedMapping, mapping); } // Should not have any duplicate property mappings. Assert.AreEqual(whichIndexIsProperty.Count, whichIndexIsProperty.Distinct().Count()); }