/// <summary> /// See whether this is a better match to the specified matching target style /// </summary> /// <param name="target">matching target style</param> /// <param name="best">current best match</param> /// <param name="matching">matching style</param> internal static bool IsBetterMatch( MatchingStyle target, MatchingStyle best, ref MatchingStyle matching ) { return(matching.IsBetterMatch(target, best)); }
/// <summary> /// Find the face exactly matching the specified style, weight and stretch. /// Returns CachedFontFace.Null if there is no matching face. /// </summary> private CachedFontFace FindExactTypeface(FontStyle style, FontWeight weight, FontStretch stretch) { MatchingStyle target = new MatchingStyle(style, weight, stretch); for (int i = 0; i < _cachedFamily.NumberOfFaces; i++) { CachedFontFace currentFace = _cachedFamily.FamilyCollection.GetCachedFace(_cachedFamily, i); if (currentFace.MatchingStyle == target) { return(currentFace); } } return(CachedFontFace.Null); }
/// <summary> /// See whether this is a better match to the specified matching target /// </summary> internal bool IsBetterMatch( MatchingStyle target, MatchingStyle best ) { double currentDiffSize = (_vector - target._vector).LengthSquared; double bestDiffSize = (best._vector - target._vector).LengthSquared; // better match found when... if (currentDiffSize < bestDiffSize) { // the distance from the current vector to target is shorter return(true); } else if (currentDiffSize == bestDiffSize) { double dotCurrent = Vector.DotProduct(_vector, target._vector); double dotBest = Vector.DotProduct(best._vector, target._vector); if (dotCurrent > dotBest) { // when distances are equal, the current vector has a stronger // projection onto target. return(true); } else if (dotCurrent == dotBest) { if (_vector.X > best._vector.X || (_vector.X == best._vector.X && (_vector.Y > best._vector.Y || (_vector.Y == best._vector.Y && _vector.Z > best._vector.Z)))) { // when projections onto target are still equally strong, the current // vector has a stronger component. return(true); } } } return(false); }
/// <summary> /// Find the face most closely matching the specified style, weight and stretch. /// Returns CachedFontFace.Null if there is no available face. /// </summary> private CachedFontFace FindNearestTypeface(FontStyle style, FontWeight weight, FontStretch stretch) { if (_cachedFamily.NumberOfFaces == 0) { return(CachedFontFace.Null); } MatchingStyle target = new MatchingStyle(style, weight, stretch); CachedFontFace bestFace = _cachedFamily.FamilyCollection.GetCachedFace(_cachedFamily, 0); MatchingStyle bestMatch = bestFace.MatchingStyle; for (int i = 1; i < _cachedFamily.NumberOfFaces; i++) { CachedFontFace currentFace = _cachedFamily.FamilyCollection.GetCachedFace(_cachedFamily, i); MatchingStyle currentMatch = currentFace.MatchingStyle; if (MatchingStyle.IsBetterMatch(target, bestMatch, ref currentMatch)) { bestMatch = currentMatch; bestFace = currentFace; } } 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> /// 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> /// See whether this is a better match to the specified matching target style /// </summary> /// <param name="target">matching target style</param> /// <param name="best">current best match</param> /// <param name="matching">matching style</param> internal static bool IsBetterMatch( MatchingStyle target, MatchingStyle best, ref MatchingStyle matching ) { return matching.IsBetterMatch(target, best); }
/// <summary> /// See whether this is a better match to the specified matching target /// </summary> internal bool IsBetterMatch( MatchingStyle target, MatchingStyle best ) { double currentDiffSize = (_vector - target._vector).LengthSquared; double bestDiffSize = (best._vector - target._vector).LengthSquared; // better match found when... if(currentDiffSize < bestDiffSize) { // the distance from the current vector to target is shorter return true; } else if(currentDiffSize == bestDiffSize) { double dotCurrent = Vector.DotProduct(_vector, target._vector); double dotBest = Vector.DotProduct(best._vector, target._vector); if(dotCurrent > dotBest) { // when distances are equal, the current vector has a stronger // projection onto target. return true; } else if(dotCurrent == dotBest) { if( _vector.X > best._vector.X || ( _vector.X == best._vector.X && ( _vector.Y > best._vector.Y || ( _vector.Y == best._vector.Y && _vector.Z > best._vector.Z)))) { // when projections onto target are still equally strong, the current // vector has a stronger component. return true; } } } return false; }
internal MatchingFaceComparer(MatchingStyle targetStyle) { _targetStyle = targetStyle; }
internal MatchingFace(Text.TextInterface.Font face) { _face = face; _style = new MatchingStyle(new FontStyle((int)face.Style), new FontWeight((int)face.Weight), new FontStretch((int)face.Stretch)); }
internal GlyphTypeface MapGlyphTypeface( FontStyle style, FontWeight weight, FontStretch stretch, CharacterBufferRange charString, CultureInfo digitCulture, ref int advance, ref int nextValid ) { int smallestInvalid = charString.Length; // Add all the cached font faces to a priority queue. MatchingStyle targetStyle = new MatchingStyle(style, weight, stretch); PriorityQueue <MatchingFace> queue = new PriorityQueue <MatchingFace>( checked ((int)_family.Count), new MatchingFaceComparer(targetStyle)); foreach (Text.TextInterface.Font face in _family) { queue.Push(new MatchingFace(face)); } // Remember the best style match. MS.Internal.Text.TextInterface.Font bestStyleTypeface = null; // Iterate in priority order. for (; queue.Count != 0; queue.Pop()) { int invalid = 0; MS.Internal.Text.TextInterface.Font font = queue.Top.FontFace; int valid = MapCharacters(font, charString, digitCulture, ref invalid); if (valid > 0) { if (smallestInvalid > 0 && smallestInvalid < valid) { // advance only to smallestInvalid because there's a better match after that advance = smallestInvalid; nextValid = 0; } else { advance = valid; nextValid = invalid; } return(new GlyphTypeface(font)); } else { if (invalid < smallestInvalid) { // keep track of the current shortest length of invalid characters, smallestInvalid = invalid; } if (bestStyleTypeface == null) { bestStyleTypeface = font; } } } // no face can map the specified character string, // fall back to the closest style match advance = 0; nextValid = smallestInvalid; Debug.Assert(bestStyleTypeface != null); return(new GlyphTypeface(bestStyleTypeface)); }