internal void Canonicalize() { if (_canonicalReferences != null) { return; } int count = this.Count; if (count == 0) { return; } // First look up the entire friendly name in the cache; this may enable us to // save working set by sharing the same array of may equal FontFamilyIdentifier. BasedFriendlyName hashKey = new BasedFriendlyName(_baseUri, _friendlyName); CanonicalFontFamilyReference[] canonicalReferences = TypefaceMetricsCache.ReadonlyLookup(hashKey) as CanonicalFontFamilyReference[]; if (canonicalReferences == null) { // We need to construct a new array. canonicalReferences = new CanonicalFontFamilyReference[count]; // Add the first canonical family reference. int i, length; int j = FindToken(_friendlyName, 0, out i, out length); canonicalReferences[0] = GetCanonicalReference(i, length); // Add subsequent family references. for (int k = 1; k < count; ++k) { j = FindToken(_friendlyName, j, out i, out length); canonicalReferences[k] = GetCanonicalReference(i, length); } // Add the array to the cache. TypefaceMetricsCache.Add(hashKey, canonicalReferences); } // for thread safety, we assign to the field only after the array is fully initialized _canonicalReferences = canonicalReferences; }
private CanonicalFontFamilyReference GetCanonicalReference(int startIndex, int length) { string normalizedString = Util.GetNormalizedFontFamilyReference(_friendlyName, startIndex, length); // For caching normalized names, we use a different type of key which does not compare equal // to the keys we used for caching friendly names. BasedNormalizedName hashKey = new BasedNormalizedName(_baseUri, normalizedString); // Look up the normalized string and base URI in the cache? CanonicalFontFamilyReference canonicalReference = TypefaceMetricsCache.ReadonlyLookup(hashKey) as CanonicalFontFamilyReference; // Do we already have a cached font family reference? if (canonicalReference == null) { // Not in cache. Construct a new font family reference. canonicalReference = CanonicalFontFamilyReference.Create(_baseUri, normalizedString); // Add it to the cache. TypefaceMetricsCache.Add(hashKey, canonicalReference); } return(canonicalReference); }
private CachedTypeface ConstructCachedTypeface() { FontStyle canonicalStyle = _style; FontWeight canonicalWeight = _weight; FontStretch canonicalStretch = _stretch; // // We always call FontFamily.FindFirstFontFamilyAndFace() method to resolve the // canonical styles since the implied styles in FontFamily name will override // the given styles in the Typeface. But we don't always use the IFontFamily // instance returned from this method because an equal instance might already be // cached. // FontFamily sourceFontFamily = FontFamily; IFontFamily firstFontFamily = sourceFontFamily.FindFirstFontFamilyAndFace( ref canonicalStyle, ref canonicalWeight, ref canonicalStretch ); if (firstFontFamily == null) { if (FallbackFontFamily != null) { sourceFontFamily = FallbackFontFamily; firstFontFamily = sourceFontFamily.FindFirstFontFamilyAndFace( ref canonicalStyle, ref canonicalWeight, ref canonicalStretch ); } if (firstFontFamily == null) { sourceFontFamily = null; firstFontFamily = FontFamily.LookupFontFamily(FontFamily.NullFontFamilyCanonicalName); } } // If it's a named font, map all occurrences of the same name to one cached IFontFamily. if (sourceFontFamily != null && sourceFontFamily.Source != null) { // We lookup in the cache to see if there is cached IFontFamily instance of the source FontFamily. Otherwise, // this IFontFamily value is added to the TypefaceMetrics cache. IFontFamily cachedValue = TypefaceMetricsCache.ReadonlyLookup(sourceFontFamily.FamilyIdentifier) as IFontFamily; if (cachedValue != null) { firstFontFamily = cachedValue; } else { TypefaceMetricsCache.Add(sourceFontFamily.FamilyIdentifier, firstFontFamily); } } ITypefaceMetrics typefaceMetrics = firstFontFamily.GetTypefaceMetrics(canonicalStyle, canonicalWeight, canonicalStretch); return(new CachedTypeface( canonicalStyle, canonicalWeight, canonicalStretch, firstFontFamily, typefaceMetrics, sourceFontFamily == null )); }