Ejemplo n.º 1
0
        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;
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        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
                       ));
        }