/// <summary> /// Constructs FontFamily from a string and an optional base URI. /// </summary> /// <param name="baseUri">Specifies the base URI used to resolve family names, typically /// the URI of the document or element that refers to the font family. Can be null.</param> /// <param name="familyName">Specifies one or more comma-separated family names, each /// of which may be either a regular family name string (e.g., "Arial") or a URI /// (e.g., "file:///c:/windows/fonts/#Arial").</param> public FontFamily(Uri baseUri, string familyName) { if (familyName == null) { throw new ArgumentNullException("familyName"); } if (baseUri != null && !baseUri.IsAbsoluteUri) { throw new ArgumentException(SR.Get(SRID.UriNotAbsolute), "baseUri"); } _familyIdentifier = new FontFamilyIdentifier(familyName, baseUri); }
/// <summary> /// Scan the friendly name string finding the first valid font family /// </summary> internal static IFontFamily FindFontFamilyFromFriendlyNameList(string friendlyNameList) { IFontFamily firstFontFamily = null; // Split limits the number of tokens in a family name. FontFamilyIdentifier identifier = new FontFamilyIdentifier(friendlyNameList, null); for (int i = 0, c = identifier.Count; firstFontFamily == null && i < c; i++) { firstFontFamily = LookupFontFamily(identifier[i]); } if (firstFontFamily == null) { // cannot find first font family, assume null font for first font family firstFontFamily = LookupFontFamily(NullFontFamilyCanonicalName); // null font family should always exist Invariant.Assert(firstFontFamily != null); } return(firstFontFamily); }
/// <summary> /// Construct an anonymous font family, i.e., a composite font that is created /// programatically instead of referenced by name or URI. /// </summary> public FontFamily() { _familyIdentifier = new FontFamilyIdentifier(null, null); _firstFontFamily = new CompositeFontFamily(); }
internal FontFamily(FontFamilyIdentifier familyIdentifier) { _familyIdentifier = familyIdentifier; }
/// <summary> /// Maps characters to one of the font families in the specified FontFamilyList. This /// function differs from MapByFontFamilyList in that it returns as soon as at least /// one character is mapped; it does not keep going until it cannot map any more text. /// </summary> private int MapOnceByFontFamilyList( CharacterBufferRange unicodeString, CultureInfo culture, CultureInfo digitCulture, FontFamily[] familyList, ref PhysicalFontFamily firstValidFamily, ref int firstValidLength, IDeviceFont deviceFont, double scaleInEm, int recursionDepth, SpanVector scaledTypefaceSpans, int firstCharIndex, out int nextValid ) { Invariant.Assert(familyList != null); int advance = 0; nextValid = 0; CharacterBufferRange mapString = unicodeString; FontStyle canonicalStyle = _canonicalStyle; FontWeight canonicalWeight = _canonicalWeight; FontStretch canonicalStretch = _canonicalStretch; // Note: FontFamilyIdentifier limits the number of family names in a single string. We // don't want to also limit the number of iterations here because if Typeface.FontFamily // has the maximum number of tokens, this should not prevent us from falling back to the // FallbackFontFamily (PS # 1148305). // Outer loop to loop over the list of FontFamily. for (int i = 0; i < familyList.Length; i++) { // grab the font family identifier and initialize the // target family based on whether it is a named font. FontFamilyIdentifier fontFamilyIdentifier = familyList[i].FamilyIdentifier; CanonicalFontFamilyReference canonicalFamilyReference = null; IFontFamily targetFamily; if (fontFamilyIdentifier.Count != 0) { // Look up font family and face, in the case of multiple canonical families the weight/style/stretch // may not match the typeface map's, since it is created w/ the first canonical family. canonicalFamilyReference = fontFamilyIdentifier[0]; targetFamily = FontFamily.LookupFontFamilyAndFace(canonicalFamilyReference, ref canonicalStyle, ref canonicalWeight, ref canonicalStretch); } else { targetFamily = familyList[i].FirstFontFamily; } int familyNameIndex = 0; // Inner loop to loop over all name tokens of a FontFamily. for (;;) { if (targetFamily != null) { advance = MapByFontFamily( mapString, culture, digitCulture, targetFamily, canonicalFamilyReference, canonicalStyle, canonicalWeight, canonicalStretch, ref firstValidFamily, ref firstValidLength, deviceFont, scaleInEm, recursionDepth, scaledTypefaceSpans, firstCharIndex, out nextValid ); if (nextValid < mapString.Length) { // only strings before the smallest invalid needs to be mapped since // string beyond smallest invalid can already be mapped to a higher priority font. mapString = new CharacterBufferRange( unicodeString.CharacterBuffer, unicodeString.OffsetToFirstChar, nextValid ); } if (advance > 0) { // found the family that shapes this string. We terminate both the // inner and outer loops. i = familyList.Length; break; } } else { // By definition null target does not map any of the input. nextValid = mapString.Length; } if (++familyNameIndex < fontFamilyIdentifier.Count) { // Get the next canonical family name and target family. canonicalFamilyReference = fontFamilyIdentifier[familyNameIndex]; targetFamily = FontFamily.LookupFontFamilyAndFace(canonicalFamilyReference, ref canonicalStyle, ref canonicalWeight, ref canonicalStretch); } else { // Unnamed FontFamily or no more family names in this FontFamily. break; } } } nextValid = mapString.Length; return(advance); }
ICollection <Typeface> IFontFamily.GetTypefaces(FontFamilyIdentifier familyIdentifier) { return(new TypefaceCollection(new FontFamily(familyIdentifier), FamilyTypefaces)); }