// Compares a set of inheritable properties taken from two objects private static bool InheritablePropertiesAreEqual(Inline firstInline, Inline secondInline) { Invariant.Assert(firstInline != null, "null check: firstInline"); Invariant.Assert(secondInline != null, "null check: secondInline"); // Compare inheritable properties DependencyProperty[] inheritableProperties = TextSchema.GetInheritableProperties(typeof(Inline)); for (int i = 0; i < inheritableProperties.Length; i++) { DependencyProperty property = inheritableProperties[i]; if (TextSchema.IsStructuralCharacterProperty(property)) { if (firstInline.ReadLocalValue(property) != DependencyProperty.UnsetValue || secondInline.ReadLocalValue(property) != DependencyProperty.UnsetValue) { return false; } } else { if (!TextSchema.ValuesAreEqual(firstInline.GetValue(property), secondInline.GetValue(property))) { return false; } } } return true; }
// Copies all structural properties from source (clearing the property) to destination. private static void TransferStructuralProperties(Inline source, Inline destination) { bool sourceIsChild = (source.Parent == destination); for (int i = 0; i < TextSchema.StructuralCharacterProperties.Length; i++) { DependencyProperty property = TextSchema.StructuralCharacterProperties[i]; if ((sourceIsChild && HasLocalInheritableStructuralPropertyValue(source)) || (!sourceIsChild && HasLocalStructuralPropertyValue(source))) { object value = source.GetValue(property); source.ClearValue(property); destination.SetValue(property, value); } } }
// Returns true if an inline has one or more structural local property values. private static bool HasLocalInheritableStructuralPropertyValue(Inline inline) { int i; for (i = 0; i < TextSchema.StructuralCharacterProperties.Length; i++) { DependencyProperty inheritableProperty = TextSchema.StructuralCharacterProperties[i]; if (!TextSchema.ValuesAreEqual(inline.GetValue(inheritableProperty), inline.Parent.GetValue(inheritableProperty))) break; } return (i < TextSchema.StructuralCharacterProperties.Length); }
// Compares all character formatting properties for two elements. // Returns true if all known properties have equal values, false otherwise. // Note that only statically known character formatting properties // are taken into account. We intentionally ignore all other properties, // because TextEditor is not aware (in general) about their semantics, // and considers unsafe to duplicate them freely. // Ignorance means deletion, which is considered as safer approach. private static bool CharacterPropertiesAreEqual(Inline firstElement, Inline secondElement) { Invariant.Assert(firstElement != null, "null check: firstElement"); if (secondElement == null) { return false; } DependencyProperty[] noninheritableProperties = TextSchema.GetNoninheritableProperties(typeof(Span)); for (int i = 0; i < noninheritableProperties.Length; i++) { DependencyProperty property = noninheritableProperties[i]; if (!TextSchema.ValuesAreEqual(firstElement.GetValue(property), secondElement.GetValue(property))) { return false; } } if (!InheritablePropertiesAreEqual(firstElement, secondElement)) { return false; } return true; }