/// <summary> /// Find the face closest to the specified style, weight and stretch. /// Returns null if there is no matching face. /// </summary> private FamilyTypeface FindNearestFamilyTypeface( FontStyle style, FontWeight weight, FontStretch stretch ) { if (_fontInfo.FamilyTypefaces == null || _fontInfo.FamilyTypefaces.Count == 0) { return(null); } FamilyTypeface bestFace = (FamilyTypeface)_fontInfo.FamilyTypefaces[0]; MatchingStyle bestMatch = new MatchingStyle(bestFace.Style, bestFace.Weight, bestFace.Stretch); MatchingStyle target = new MatchingStyle(style, weight, stretch); for (int i = 1; i < _fontInfo.FamilyTypefaces.Count; i++) { FamilyTypeface currentFace = (FamilyTypeface)_fontInfo.FamilyTypefaces[i]; MatchingStyle currentMatch = new MatchingStyle(currentFace.Style, currentFace.Weight, currentFace.Stretch); if (MatchingStyle.IsBetterMatch(target, bestMatch, ref currentMatch)) { bestFace = currentFace; bestMatch = currentMatch; } } return(bestFace); }
/// <summary> /// Find the face exactly matching the specified style, weight and stretch. /// Returns null if there is no matching face. /// </summary> private FamilyTypeface FindExactFamilyTypeface( FontStyle style, FontWeight weight, FontStretch stretch ) { if (_fontInfo.FamilyTypefaces == null || _fontInfo.FamilyTypefaces.Count == 0) { return(null); } MatchingStyle target = new MatchingStyle(style, weight, stretch); foreach (FamilyTypeface currentFace in _fontInfo.FamilyTypefaces) { MatchingStyle currentMatch = new MatchingStyle(currentFace.Style, currentFace.Weight, currentFace.Stretch); if (currentMatch == target) { return(currentFace); } } return(null); }
/// <summary> /// Finds the best match among the candidates. /// </summary> /// <param name="binder">The binder that is requesting the match.</param> /// <param name="args">The args passed in to the invocation.</param> /// <param name="genericArgs">The generic args if any.</param> /// <param name="candidates">The candidate methods to use for the match..</param> /// <param name="matching">if set to <c>MatchingStyle.AssignableFrom</c>, uses a more lax matching approach for arguments, with IsAssignableFrom instead of == for arg type, /// and <c>MatchingStyle.GenericTypeHint</c> tries to use the generic arguments as type hints if they match the # of args.</param> private IInvocable FindBestMatchImpl(DynamicMetaObjectBinder binder, object[] args, List <Type> genericArgs, IEnumerable <IInvocable> candidates, MatchingStyle matching) { dynamic dynamicBinder = binder.AsDynamicReflection(); for (int i = 0; i < args.Length; i++) { var index = i; if (args[index] != null) { switch (matching) { case MatchingStyle.ExactType: candidates = candidates.Where(x => x.Parameters[index].ParameterType.IsAssignableFrom(GetArgumentType(args[index]))); break; case MatchingStyle.AssignableFrom: candidates = candidates.Where(x => x.Parameters[index].ParameterType.IsEquivalentTo(GetArgumentType(args[index]))); break; case MatchingStyle.ExactTypeGenericHint: candidates = candidates.Where(x => x.Parameters.Count == genericArgs.Count && x.Parameters[index].ParameterType.IsEquivalentTo(genericArgs[index])); break; case MatchingStyle.AssignableFromGenericHint: candidates = candidates.Where(x => x.Parameters.Count == genericArgs.Count && x.Parameters[index].ParameterType.IsAssignableFrom(genericArgs[index])); break; default: break; } } IEnumerable enumerable = dynamicBinder.ArgumentInfo; // The binder has the extra argument info for the "this" parameter at the beginning. if (enumerable.Cast <object>().ToList()[index + 1].AsDynamicReflection().IsByRef) { candidates = candidates.Where(x => x.Parameters[index].ParameterType.IsByRef); } // Only filter by matching generic argument count if the generics isn't being used as parameter type hints. if (genericArgs.Count > 0 && matching != MatchingStyle.AssignableFromGenericHint && matching != MatchingStyle.ExactTypeGenericHint) { candidates = candidates.Where(x => x.IsGeneric && x.GenericParameters == genericArgs.Count); } } return(candidates.FirstOrDefault()); }